<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------

namespace app\common;

use app\model\activity\free\FreeRuleProduct;
use app\model\activity\free\StoreFree;
use app\model\activity\free\StoreFreeRule;
use app\model\order\OrderItems;
use app\model\order\Orders;
use app\model\order\StoreCart;
use app\model\order\StoreOrder;
use app\model\product\sku\StoreProductAttrValue;
use app\model\user\UserAddress;
use app\outapi\controller\StoreProduct;
use app\services\activity\coupon\StoreCouponIssueServices;
use app\services\order\StoreCartServices;
use app\services\order\StoreOrderCreateServices;
use app\services\order\StoreOrderServices;
use crmeb\exceptions\ApiException;

/**
 * 订单处理工具类
 */
class OrderTool
{
    /**
     * @var float
     * 订单总价
     */
    public $totalPrice = 0.00;

    /**
     * @var float
     * 订单运费
     */
    public $shippingPrice = 0.00;

    /**
     * @var float
     * 优惠券价格
     */
    public $couponPrice = 0.00;
    /**
     * @var int
     * 优惠券ID
     */
    public $couponId = 0;

    /**
     * @var float
     * 商品金额
     */
    public $productPrice = 0.00;

    /**
     * @return OrderTool
     * 静态调用入口
     */
    public static function init() : OrderTool
    {
        return new static();
    }

    /**
     * @param $userId
     * @param $fields
     * @return UserAddress|array|mixed|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取订单默认地址
     */
    public function defaultAddress($userId, $fields = ['*'], $addressId = 0, $with = []) : array
    {
        $result = UserAddress::with($with)->where([
            ['uid', '=', $userId],
            ['is_del', '=', 0],
        ]);
        $result = $addressId ? $result->where('id', $addressId) : $result->where('is_default', 1);
        $result = $result->field($fields)->find();

        return !empty($result) ? $result->toArray() : [];
    }

    /**
     * @param $orderId
     * @param $userId
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取订单详情
     */
    public function getOrder($orderId, $userId = 0)
    {
        $result = Orders::where([
            ['id', '=', $orderId],
            ['is_del', '=', 0],
        ]);
        $result = $userId ? $result->where('uid', $userId) : $result;
        $result = $result->find();

        return !empty($result) ? $result->toArray() : [];
    }

    /**
     * @param $orderId
     * @param $userId
     * @return Orders
     * 订单支付
     */
    public function orderPay($orderId, $userId = 0)
    {
        $query = Orders::where('id', $orderId);
        $query = $userId ? $query->where('uid', $userId) : $query;

        return $query->update(['status' => 1, 'pay_status' => 1, 'pay_time' => time()]);
    }

    /**
     * @param $orderId
     * @param $userId
     * @return Orders
     * 订单退款
     */
    public function orderRefund($orderId, $userId = 0)
    {
        $query = Orders::where('id', $orderId);
        $query = $userId ? $query->where('uid', $userId) : $query;

        return $query->update(['status' => 0, 'pay_status' => 0, 'pay_time' => 0]);
    }

    /**
     * @param $orderId
     * @param int $userId
     * @return mixed
     * 订单取消
     */
    public function ordercancel($orderId, $userId = 0){
        $query = Orders::where('id', $orderId);
        $query = $userId ? $query->where('uid', $userId) : $query;

        return $query->update(['status' => 4]);
    }

    /**
     * @param $freeArray
     * @return void
     * 判断满减是否符合
     */
    public function checkFreeRule($free_json)
    {
        $freeArray = $free_json ? json_decode($free_json, true) : [];
        if(empty($freeArray) || empty($freeArray[0]['free_rule_id'])) {
            throw new ApiException(31007);
        }
        // 摘到free id
        $free_rule = StoreFreeRule::with('free')->where('id', $freeArray[0]['free_rule_id'])->find();
        if(!$free_rule || !$free_rule->free) {
            throw new ApiException(31007);
        }
        if($free_rule->free->start_time > time() || $free_rule->free->end_time <= time()) {
            throw new ApiException(31006);
        }
        if ($free_rule->free->status == 0) {
            throw new ApiException(31008);
        }

        foreach ($freeArray as $item) {
            $free_rule_product = FreeRuleProduct::where('product_attr_value_unique', $item['product_attr_value_unique'])->where('free_rule_id', $free_rule->id)->find();
            if (!$free_rule_product || $free_rule_product->activity_count  < $item['give_count']) {
                throw new ApiException(31026);
            }
        }

    }

    /**
     * @param $seckillProductArray
     * @return void
     * 判断秒杀条件是否符合
     */
    public function checkSeckillProduct($seckillProductArray)
    {
        if(empty($seckillProductArray)) {
            throw new ApiException(31009);
        }
        if($seckillProductArray['count'] == 0) {
            throw new ApiException(31010);
        }
        /*if($seckillProductArray['seckill']['status'] == 0) {
            throw new ApiException(31011);
        }*/
    }

    /**
     * @param $storeCardIds
     * @param $userId
     * @return StoreCart[]|array|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取购物车产品
     */
    public function getOrderStoreCard($storeCardIds, $userId)
    {
        $result = StoreCart::with(['productInfo', 'attrInfo', 'seckillProduct.seckill'])->where([
            ['id', 'IN', $storeCardIds],
            ['is_del', '=', 0],
            ['uid', 'IN', $userId],
        ])->select()->toArray();

        return $result;
    }

    /**
     * @param $freeObj
     * @param $price
     * @param $cartNum
     * @return array
     * 获取赠品信息
     */
    public function getOrderFreeInfo($freeObj, $price, $cartNum)
    {
        return (app()->make(StoreCartServices::class))->getFreeInfo($freeObj, $price, $cartNum);
    }

    public function couponInit($uid,$cartIds,$coupon_id){

        $couponServers = app()->make(StoreCouponIssueServices::class);
        $list = $couponServers->beUsableCouponList($uid,$cartIds,false);
        $list = array_column($list,null,'cid');
        $coupon_price = 0;
        if ($coupon_id > 0) {
            if(isset($list[$coupon_id])) $coupon_price = $list[$coupon_id]['coupon_price'];
        }else{//自动计算可使用优惠券
            foreach($list as $val){
                if($coupon_price == 0) {
                    $coupon_price = $val['coupon_price'];
                    $coupon_id = $val['cid'];
                }
                if($val['coupon_price'] > $coupon_price){
                    $coupon_price = $val['coupon_price'];
                    $coupon_id = $val['cid'];
                }
            }
        }
        $this->couponPrice = $coupon_price;
        $this->couponId = $coupon_id;
    }

    /**
     * @param $userId
     * @param $storeCardIds
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取订单商品
     */
    public function getCartInfo($userId, $storeCardIds, $coupon_id) : array
    {
        $result = [];
        $address = $this->defaultAddress($userId);
        // 判断如果没有城市的话, 则提示异常
        $city_id = $address['city_id'] ?? 0;
        $storeCardObj = StoreCart::with(['productInfo', 'attrInfo', 'seckillProduct.seckill'])->where([
            ['id', 'IN', $storeCardIds],
            ['is_del', '=', 0],
            ['uid', 'IN', $userId],
        ])->select();


        foreach($storeCardObj as $key => $val) {
            //重量
            $weight = $val->attrInfo->weight ?? 0;
            //商品属性对应库存
            $stock = $val->attrInfo->stock ?? 0;
            //商品属性金额
            $price = $val->attrInfo->price ?? 0.00;
            //活动价格
            $seckillPrice = $val->seckillProduct->activity_price ?? $price;
            /**
             * 累加订单价格
             */

            $productPrice = bcmul($seckillPrice, $val->cart_num, 2);
            $shippingPrice = (app()->make(StoreOrderServices::class)->getShippingPrice($city_id, $val->product_id, $weight, $val->cart_num, $val->free_rule_uniques, $val->seckill_id, $coupon_id));
            //总价
            $this->productPrice += $productPrice;
            //运费
            $this->shippingPrice += $shippingPrice;

            $this->totalPrice = bcadd($productPrice, $shippingPrice, 2);

            $result[] = [
                'id' => $val->id,
                'image' => $val->attrInfo->image ?? '',
                'store_name' => $val->productInfo->store_name ?? '',
                'attr_value' => $val->attrInfo->suk ?? '',
                'cart_num' => $val->cart_num,
                'free_info' => FreeTool::init()->getAvailableFree($val->product_attr_unique, (bool)($val->seckillProduct), $coupon_id),
                'price' => $price,
                'activity_price' => $seckillPrice
            ];
        }

        return $result;
    }


    /**
     *
     * 获取满赠介绍结构
     * @param $free_json
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getFreeProductInfo($free_json)
    {
//        $free_json = (json_decode($free_json, true)) ?? [];
        $free_products = $free_info = [];
        foreach ($free_json as $value) {

            $free_rule_count = StoreFreeRule::hasWhere('free', function ($query) {
                $query->where('start_time' > time())->where('end_time', time())->where('is_del', 0)->where('status', 1);
            })->where('StoreFreeRule.id', $value['free_rule_id'])->count();
            if ($free_rule_count) {
                $productAttrValue = StoreProductAttrValue::with(['product'])->where('unique', $value['product_attr_value_unique'])->find();
                $free_products[] = [
                    'free_rule_id'  =>  $value['free_rule_id'],
                    "store_name"=> ($productAttrValue->product) ? $productAttrValue->product->store_name : '',
                    "unique"=>  $value['product_attr_value_unique'] ?? '',
                    "suk"=> $productAttrValue->suk ?? '',
                    "image"=> $productAttrValue->image ?? '',
                    "price"=> $productAttrValue->price ?? '',
                    "show_price"=> "0.00",
                    "give_count"=> $value['give_count']
                ];
            }

        }
        
        if (!empty($free_products)) {
            $free_info['num'] = count($free_products);
            $free_info['list'] = $free_products;
        }
        return $free_info;
    }

    /**
     * @param $prefix
     * @return string
     * @throws \Exception
     * 获取订单编码
     */
    public function getOrderSn($prefix = 'cp') : string
    {
        return (app()->make(StoreOrderCreateServices::class))->getNewOrderId($prefix);
    }

    /**
     * @param $isSeckill
     * @param $limit
     * @return array
     * @throws \think\db\exception\DbException
     * 随机获取商品信息
     */
    public function getRandomProduct($isSeckill = 0, $limit = 6)
    {
        $result = [];
        $productRow = \app\model\product\product\StoreProduct::where([
            ['is_seckill', '=', $isSeckill],
        ])->orderRand()->limit(6)->select()->toArray();
        foreach($productRow as $key => $val) {
            $result[] = [
                'id' => $val['id'],
                'image' => $val['image'],
                'recommend_image' => $val['recommend_image'],
                'store_name' => $val['store_name'],
                'price' => $val['price'],
                'is_seckill' => $val['is_seckill'],
                'is_seckill_name' => \app\model\product\product\StoreProduct::IS_SECKILL_NAME[$val['is_seckill']],
                'presale_time' => ($val['presale_day'] ?? 1) * 24 . 'H发货',
                'is_buy_info' => OrderItems::where('product_id', $val['id'])->count() . ' 人已买过',
            ];
        }

        return $result;
    }

    /**
     *
     * 获取商品的重量
     * @param $cart
     * @return void
     */
    public function getOrderWeightByCart($cart)
    {
        // 商品的重点包括本体的重量跟赠品的重量
        $local_weight = $cart['attrInfo']['weight'] ?? 0;
        if (!$local_weight) return 0;
        $free_json = $cart['free_json'] ?? null;
        if (!$free_json) return $local_weight;
        $free_rule_products = (json_decode($free_json, true)) ?? [];
        $free_rule_unique_arr = array_column($free_rule_products, 'product_attr_value_unique');
        $free_weight = StoreProductAttrValue::whereIn('unique', $free_rule_unique_arr)->sum('weight');

        return $local_weight + $free_weight;
    }


}